<?php

/**
 * \file
 * Classe `member`.
 */
 
namespace pilar\ObjectCollections /* \cond */ ; /* \endcond */
{

/**
 * Membre d'une jointure d'une collection d'objets d'une entité de données.
 *
 * \since 08/10/2008
 * \author Matthieu OVIEDO <matthieu.oviedo@gmail.com>
 */
class Member {

/**
 * Jointure parente du membre.
 *
 * \since 08/10/2008
 */
protected $_parentJoin;


/**
 * Membre d'entité type du membre.
 *
 * \since 08/10/2008
 */
protected $_entityMember;


/**
 * Champs instanciés du membre.
 *
 * \since 08/10/2008
 */
private $_fields;


/**
 * Constructeur.
 *
 * \since 08/10/2008
 * \param $parentJoin Jointure parente du membre.
 * \param $entityMember Membre d'entité type du membre.
 */
public function __construct($parentJoin, $entityMember) {
 $this->_parentJoin = $parentJoin;
 $this->_entityMember = $entityMember;
 $this->_fields = array();
}


/**
 * Accède à un champ du membre par son nom.
 *
 * Les champs sont chargés dynamiquement et mis en cache.
 *
 * \param $fieldName Nom du champ requis.
 * \return Le champ requis.
 *
 * \since 08/10/2008
 */
public function field($fieldName = 'value') {
 // Si le champ a déjà été chargé on retourne directement son instance :
  if(isset($this->_fields[$fieldName])) {
   return $this->_fields[$fieldName];
  }
  
 // A ce stade il faut instancier un nouveau champ.
 
 // Evaluation du champ de l'entité :
  $entityField = $this->_entityMember->field($fieldName);
  
 // Création du nouveau champ :
  $field = new Field(
   $this,
   $entityField
  );
 
 // Ajout du champ à la liste locale :
  $this->_fields[$fieldName] = $field;
  
 return $field;
}


/**
 * Accède à un sous élément du membre.
 *
 * \param $elName Nom de l'élément.
 * \return Élement.
 *
 * \since 23/02/2009
 */
public function __get($elName) {
 return $this->field($elName); /* Un membre simple n'a que des champs
                                     comme sous-éléments. */
}


/**
 * Permet de spécifier les valeurs a assigner aux champs du membre lors de
 * l'opération de mise à jour de la collection d'objets parente.
 *
 * Si \c $values est un scalaire alors il est assigné au champ principal
 * du membre, sinon il est assigné aux champs en fonction de leur nom.
 *
 * \since 08/10/2008
 * \param $values Valeurs à assigner aux champs du membre.
 */
public function set($value) {
 // Si la valeur est un scalaire on l'assigne au champ principal :
  if(!is_array($values)) $this->__get('value')->set($values);
  else {
   // Sinon on assigne successivement les valeurs aux champs :
    foreach($values as $fieldName => $value) {
     $this->__get($fieldName)->set($value);
    }
  }
}


/**
 * Champs du membre.
 *
 * \since 08/10/2008
 * \return Champs du membre sous la forme <tt>{ $fieldName => $field }</tt>.
 */
public function fields() {
 return $this->_fields;
}


/**
 * Accède à la jointure parente du membre.
 *
 * \since 08/10/2008
 * \return Jointure parente du membre.
 */
public function parentJoin() {
 return $this->_parentJoin;
}


/**
 * Accède au membre d'entité associé au membre.
 *
 * \since 07/03/2009
 * \return Membre d'entité associé au membre.
 */
public function entityMember() {
 return $this->_entityMember;
}


/**
 * Accède à l'indexe SQL associé au champ principal du membre.
 *
 * \since 08/10/2008
 * \return Indexe SQL du champ principal du membre.
 */
public function sqlIdx() {
 return $this->field('value')->sqlIdx();
}


/**
 * Génère le code SQL associé au champ principal du membre.
 *
 * \since 08/10/2008
 * \return Code SQL associé au champ principal du membre.
 */
public function sqlCode() {
 return $this->field('value')->sqlCode();
}

} // Class.

} // Namespace.

?>
